<template>
  <basic-layout
    title="DeepSeek AI"
    class="deepseek-container"
    showBack
  >
    <div class="chat-container" ref="chatContainer">
      <div class="messages">
        <div
          v-for="(message, index) in messages"
          :key="index"
          :class="['message-item', message.role]"
        >
          <template v-if="message.role === 'assistant'">
            <van-image
              round
              width="40"
              height="40"
              src="https://api.dicebear.com/7.x/bottts/svg?seed=deepseek"
              class="avatar"
            />
          </template>
          <div class="message-content">
            <div class="message-bubble" v-html="formattedMessages.get(index) || message.content">
            </div>
            <div v-if="isTyping && index === messages.length - 1" class="typing-indicator">
              <span></span>
              <span></span>
              <span></span>
            </div>
          </div>
          <template v-if="message.role === 'user'">
            <van-image
              round
              width="40"
              height="40"
              :src="userAvatar"
              class="avatar"
            />
          </template>
        </div>
      </div>
    </div>

    <div class="input-panel">
      <van-field
        v-model="userInput"
        class="message-input"
        :border="false"
        :autosize="{ minHeight: 20, maxHeight: 100 }"
        type="textarea"
        placeholder="输入您的问题..."
        @keypress.enter.prevent="sendMessage"
      >
        <template #button>
          <van-button
            size="small"
            type="primary"
            :loading="loading"
            :disabled="!userInput.trim() || loading"
            @click="sendMessage"
          >
            {{ loading ? '思考中...' : '发送' }}
          </van-button>
        </template>
      </van-field>
    </div>

    <van-overlay :show="loading" class="loading-overlay">
      <div class="loading-content">
        <van-loading type="spinner" color="#1989fa" size="24px" />
        <span class="loading-text">AI思考中...</span>
      </div>
    </van-overlay>
  </basic-layout>
</template>

<script lang="ts" setup>
import { ref, onMounted, nextTick } from 'vue'
import { showLoadingToast, closeToast } from 'vant'
import { marked } from 'marked'
import DOMPurify from 'dompurify'
import { getEnvConfig } from '@/utils/env'

const chatContainer = ref<HTMLElement | null>(null)
const userInput = ref('')
const loading = ref(false)
const userAvatar = 'https://fastly.jsdelivr.net/npm/@vant/assets/cat.jpeg'

const messages = ref<Array<{role: 'user' | 'assistant', content: string}>>([
  {
    role: 'assistant',
    content: '你好！我是 DeepSeek AI 助手，很高兴为您服务。请问有什么我可以帮您的吗？'
  }
])

const formattedMessages = ref<Map<number, string>>(new Map())

const currentMessageContent = ref('')
const isTyping = ref(false)

const { BASE_API } = getEnvConfig()

const formatMessageAsync = async (content: string, index: number) => {
  const html = await marked(content)
  const sanitized = DOMPurify.sanitize(html)
  formattedMessages.value.set(index, sanitized)
}

const scrollToBottom = () => {
  if (chatContainer.value) {
    nextTick(() => {
      chatContainer.value!.scrollTop = chatContainer.value!.scrollHeight
    })
  }
}

const sendMessage = async () => {
  if (!userInput.value.trim() || loading.value) return

  const userMessage = userInput.value
  messages.value.push({
    role: 'user',
    content: userMessage
  })
  userInput.value = ''
  scrollToBottom()

  loading.value = true
  isTyping.value = true
  currentMessageContent.value = ''

  try {
    // 创建一个新的消息占位
    messages.value.push({
      role: 'assistant',
      content: ''
    })
    const messageIndex = messages.value.length - 1

    const response = await fetch(`${BASE_API}/api/deepseek`, {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json',
      },
      body: JSON.stringify({
        messages: messages.value.slice(0, -1), // 不发送空的占位消息
      })
    })

    if (!response.ok) {
      throw new Error(`HTTP error! status: ${response.status}`)
    }

    const reader = response.body!.getReader()
    const decoder = new TextDecoder()

    while (true) {
      const { value, done } = await reader.read()
      if (done) break

      const chunk = decoder.decode(value)
      const lines = chunk.split('\n')

      for (const line of lines) {
        if (line.startsWith('data: ')) {
          const data = line.slice(5).trim()

          // 忽略连接成功消息
          if (data === '{"content": "连接成功"}') continue

          // 检查是否是结束标记
          if (data === '{"done":true}') {
            isTyping.value = false
            continue // 使用 continue 而不是 break
          }

          try {
            const parsed = JSON.parse(data)
            if (parsed.error) {
              throw new Error(parsed.message)
            }

            if (parsed.content) {
              currentMessageContent.value += parsed.content
              messages.value[messageIndex].content = currentMessageContent.value
              await formatMessageAsync(currentMessageContent.value, messageIndex)
              scrollToBottom()
            }
          } catch (e) {
            console.error('Error parsing chunk:', e)
          }
        }
      }
    }

  } catch (error) {
    console.error('Error:', error)
    messages.value.pop() // 移除空的占位消息
    messages.value.push({
      role: 'assistant',
      content: `抱歉，发生错误：${error.message}`
    })
  } finally {
    loading.value = false
    isTyping.value = false
    currentMessageContent.value = ''
    scrollToBottom()
  }
}

onMounted(() => {
  scrollToBottom()
})
</script>

<style lang="less" scoped>
.deepseek-container {
  display: flex;
  flex-direction: column;
  height: 100vh;
  background: #f7f7f7;
}

.chat-container {
  flex: 1;
  overflow-y: auto;
  padding: 16px;
  scroll-behavior: smooth;

  .messages {
    display: flex;
    flex-direction: column;
    gap: 16px;
  }

  .message-item {
    display: flex;
    gap: 12px;
    opacity: 1;
    transform: translateY(0);
    transition: all 0.3s ease;

    &.user {
      flex-direction: row-reverse;

      .message-content {
        align-items: flex-end;

        .message-bubble {
          background-color: #95ec69;
          border-radius: 12px 4px 12px 12px;
        }
      }
    }

    &.assistant {
      .message-bubble {
        background-color: #fff;
        border-radius: 4px 12px 12px 12px;
        box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
      }
    }

    .avatar {
      flex-shrink: 0;
    }
  }
}

.message-content {
  flex: 1;
  max-width: 70%;

  .message-bubble {
    padding: 12px 16px;
    font-size: 15px;
    line-height: 1.5;
    word-break: break-word;

    :deep(p) {
      margin: 0;
    }

    :deep(pre) {
      background: #f8f8f8;
      padding: 12px;
      border-radius: 4px;
      overflow-x: auto;
      margin: 8px 0;

      code {
        font-family: monospace;
        font-size: 14px;
      }
    }

    :deep(code) {
      background: #f0f0f0;
      padding: 2px 4px;
      border-radius: 4px;
      font-size: 14px;
    }
  }
}

.input-panel {
  background-color: #fff;
  border-top: 1px solid #eee;
  padding: 8px 16px;
  position: sticky;
  bottom: 0;

  .message-input {
    background-color: #f7f7f7;
    border-radius: 4px;

    :deep(.van-field__body) {
      display: flex;
      align-items: flex-end;
    }

    :deep(.van-button) {
      margin-left: 8px;
      height: 36px;
    }
  }
}

.typing-indicator {
  display: flex;
  gap: 4px;
  padding: 8px 12px;
  margin-top: 4px;
  background: rgba(0, 0, 0, 0.05);
  border-radius: 10px;
  width: fit-content;

  span {
    width: 6px;
    height: 6px;
    background: #90939980;
    border-radius: 50%;
    animation: bounce 1.4s infinite ease-in-out;

    &:nth-child(1) { animation-delay: -0.32s; }
    &:nth-child(2) { animation-delay: -0.16s; }
  }
}

@keyframes bounce {
  0%, 80%, 100% { transform: scale(0); }
  40% { transform: scale(1); }
}

.loading-overlay {
  display: flex;
  align-items: center;
  justify-content: center;

  .loading-content {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 8px;
    padding: 16px;
    background: rgba(255, 255, 255, 0.9);
    border-radius: 8px;
  }

  .loading-text {
    color: #666;
    font-size: 14px;
  }
}

.message-item {
  animation: messageIn 0.3s ease-out;
}

@keyframes messageIn {
  from {
    opacity: 0;
    transform: translateY(20px);
  }
  to {
    opacity: 1;
    transform: translateY(0);
  }
}

.message-bubble {
  &.typing {
    .char {
      opacity: 0;
      animation: typeIn 0.1s ease-in-out forwards;
    }
  }
}

@keyframes typeIn {
  from {
    opacity: 0;
    transform: translateY(4px);
  }
  to {
    opacity: 1;
    transform: translateY(0);
  }
}

.message-bubble {
  background: #fff;
  border-radius: 12px;
  padding: 12px 16px;
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.08);
  transition: all 0.3s ease;

  &:hover {
    box-shadow: 0 4px 12px rgba(0, 0, 0, 0.12);
  }
}

:deep(pre) {
  background: #2d2d2d;
  color: #ccc;
  padding: 16px;
  border-radius: 8px;
  margin: 12px 0;

  code {
    font-family: 'Fira Code', monospace;
    font-size: 14px;
  }
}

:deep(code) {
  background: #f4f4f4;
  color: #e96900;
  padding: 2px 6px;
  border-radius: 4px;
  font-size: 14px;
  font-family: 'Fira Code', monospace;
}

.chat-container {
  &::-webkit-scrollbar {
    width: 6px;
  }

  &::-webkit-scrollbar-track {
    background: transparent;
  }

  &::-webkit-scrollbar-thumb {
    background: rgba(0, 0, 0, 0.2);
    border-radius: 3px;

    &:hover {
      background: rgba(0, 0, 0, 0.3);
    }
  }
}
</style>
